﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPOI.HSSF.UserModel;
using System.IO;
using NPOI.SS.UserModel;
using WebeTerm.RobotBook;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Text.RegularExpressions;

namespace WebeTerm.RobotExecute
{
    public partial class frmMain : Form
    {
        private bool IsPause = false;
        private JavaScriptSerializer jss = new JavaScriptSerializer();
        private RobotBookPlugIn plugIn = new RobotBookPlugIn();
        private RobotBookConfig plugInConfig = new RobotBookConfig();
        public frmMain()
        {
            InitializeComponent();
            this.Load += (o, e) => {
                using (FileStream fs = new FileStream(@"Cabins.txt", FileMode.Open))
                {
                    StreamReader sr = new StreamReader(fs, Encoding.UTF8);
                    sr.ReadToEnd().Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(l =>
                    {
                        var singleRow = l.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                        int indexOf = 100;
                        singleRow[1].Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(c =>
                        {
                            CabinChar item = new CabinChar() { AirWay = singleRow[0] };
                            item.CabinCharCode = c;
                            item.Weight = indexOf--;
                            plugInConfig.CabinChars.Add(item);
                        });
                    });
                }
                using (FileStream fs = new FileStream(@"eTermConfig.Json", FileMode.Open))
                {
                    StreamReader sr = new StreamReader(fs, Encoding.UTF8);

                    var config = jss.Deserialize<PlugIns.eTermConfig>(sr.ReadToEnd());
                    plugIn.Config = config;
                }

                string ssCommand = null;
                try
                {
                    using (FileStream fs = new FileStream(@"SSCommand.txt", FileMode.Open))
                    {
                        StreamReader sr = new StreamReader(fs, Encoding.UTF8);

                        ssCommand = sr.ReadToEnd();
                        plugInConfig.SSCommand = ssCommand;
                    }
                }
                catch {  }

                plugIn.OneTermDisconnected += (o1, e1) =>
                {
                    ShowPATLog(@"配置已断开", string.Empty, LogAcion.ERROR);
                    //Console.WriteLine(@"OneTermDisconnected...");
                };
                plugIn.OneTermValidated += (o1, e1) =>
                {
                    ShowPATLog(@"配置已登录成功", string.Empty, LogAcion.DEBUG);
                };
                plugIn.OneTermReadPacket += (o1, e1) =>
                {
//                    Console.WriteLine(string.Format(@"----------------------------
//{0}
//{1}
//----------------------------", e1.PacketName, e1.PacketResult));
                    ShowPATLog(e1.PacketResult, e1.PacketName, LogAcion.INFO);
                };
                plugIn.OnUnPackResult += (o1, e1) =>
                {
                    //if(Regex.IsMatch(e.PlugInResult.ToDisplay(),@"返扣\:", RegexOptions.IgnoreCase| RegexOptions.Multiline))
                    //    Console.WriteLine(e.PlugInResult.ToDisplay());
                };

                plugIn.UnPacketResultWorks.Add(new PlugIns.UnPacketStreamWorker((e1) =>
                {
                    Console.WriteLine(e1.PlugInResult.ToDisplay());
                    var value = e1.PlugInResult.ToDisplay();
                    var m = Regex.Matches(value, @"((PNR|大编号)\:([A-Z0-9]+))+", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    ShowPATLog(value, string.Empty, LogAcion.INFO);
                    if (e1.PlugInResult is RobotBookResult)
                        ShowPATObject(string.Empty, (e1.PlugInResult as RobotBookResult).RobotRequire, Action.EDIT);
                    if (m.Count == 2)
                    {
                        //rbtConfig.PnrNo = m[1].Groups[3].Value;
                        //rbtConfig.Code = m[0].Groups[3].Value;
                        //rebate.PlugInConfigJSon = jss.Serialize(rbtConfig);

                        //rebate.UnPacketResultWorks.Add(new PlugIns.UnPacketStreamWorker((e1) =>
                        //{
                        //    Console.WriteLine(e1.PlugInResult.ToDisplay());
                        //}));

                        //rebate.Execute();
                        //rbtConfig.PnrNo = m.Groups[2].Value;
                        //rbtConfig.Code = m.Groups[2].Value;
                    }
                    else if(m.Count==1) { 
                        
                    }
                    //if(e.PlugInResult.
                }));
                
            };
        }

        private void btnUnPackExcel_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                lstQuene.Items.Clear();
                tabControl1.SelectedTab = tabPage2;
                btnPAT.Enabled = true;
                new Task(new System.Action(delegate { UnpackExcel(openFileDialog1.FileName); })).Start();
            }
        }
        #region 导出EXCEl
        /// <summary>
        /// 导出EXCEL
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreateExcel_Click(object sender, EventArgs e)
        {
//#if DEBUG
//            MessageBox.Show(string.Format("提示信息：\r\nDEBUG版本已禁用该功能。", 0), @"软提醒", MessageBoxButtons.OK);
//#else
            if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                ExportExcel(saveFileDialog1.FileName);
            }
//#endif
        }

        void ExportExcel(string fileName = "")
        {
            using (FileStream ms = new FileStream(fileName, FileMode.OpenOrCreate))
            {
                IWorkbook workbook = new HSSFWorkbook();//创建Workbook对象
                ISheet sheet = workbook.CreateSheet(string.Format("订座结果导出{0}", DateTime.Now.ToString(@"yyyyMMddHH")));//创建工作表
                IRow row = sheet.CreateRow(0);//在工作表中添加一行

                ICell cell_1 = row.CreateCell(0);//在行中添加一列
                cell_1.SetCellValue("乘客");//设置列的内容

                ICell cell = row.CreateCell(1);//在行中添加一列
                cell.SetCellValue("出发城市");//设置列的内容

                ICell cel2 = row.CreateCell(2);//在行中添加一列
                cel2.SetCellValue("到达程市");//设置列的内容

                ICell cel3 = row.CreateCell(3);//在行中添加一列
                cel3.SetCellValue("去程日期");//设置列的内容

                ICell cel_3 = row.CreateCell(4);//在行中添加一列
                cel_3.SetCellValue("返程日期");//设置列的内容

                ICell cel4 = row.CreateCell(5);//在行中添加一列
                cel4.SetCellValue("航空公司");//设置列的内容

                ICell cel6 = row.CreateCell(6);//在行中添加一列
                cel6.SetCellValue("航班号");//设置列的内容

                ICell cel5 = row.CreateCell(7);//在行中添加一列
                cel5.SetCellValue("舱位");//设置列的内容

                ICell cel7 = row.CreateCell(8);//在行中添加一列
                cel7.SetCellValue("PNR");//设置列的内容

                ICell cel8 = row.CreateCell(9);//在行中添加一列
                cel8.SetCellValue("大编号");//设置列的内容

                ICell cel9 = row.CreateCell(10);//在行中添加一列
                cel9.SetCellValue("返扣");//设置列的内容

                int rowIndex = 0;
                lstQuene.Items.Cast<ListViewItem>().Select(l => l.Tag as RequireBook).ToList().ForEach(l =>
                {
                    
                    //l.Results.ForEach(r =>
                    //{
                        row = sheet.CreateRow(++rowIndex);//在工作表中添加一行

                        cell = row.CreateCell(0);//在行中添加一列
                        cell.SetCellValue( string.Join(",", l.Passengers.Select(q=>q.Name).ToArray()));//设置列的内容



                        cell = row.CreateCell(1);//在行中添加一列
                        cell.SetCellValue(string.IsNullOrEmpty(l.RetDate) ?l.Dept: l.Dest);//设置列的内容

                        cel2 = row.CreateCell(2);//在行中添加一列
                        cel2.SetCellValue(string.IsNullOrEmpty(l.RetDate) ? l.Dest : l.Dept);//设置列的内容

                        cel3 = row.CreateCell(3);//在行中添加一列
                        cel3.SetCellValue(l.DeptDate);//设置列的内容

                        cel4 = row.CreateCell(4);//在行中添加一列
                        cel4.SetCellValue(l.RetDate);//设置列的内容

                        cel5 = row.CreateCell(5);//在行中添加一列
                        cel5.SetCellValue(l.AirWay);//设置列的内容

                        var flightNo = string.Join(",",
                            l.AvResultItem
                                .Select(c => Regex.Match(c, @"^(\,)?([A-Z0-9]+)\s+", RegexOptions.IgnoreCase | RegexOptions.Multiline)
                                .Groups[2].Value)
                                .ToArray()
                                );
                        cel6 = row.CreateCell(6);//在行中添加一列
                        cel6.SetCellValue(flightNo);//设置列的内容

                        var cabins = string.Join(",",
        l.AvResultItem
            .Select(c => Regex.Match(c, @"^(\,)?([A-Z0-9]+)\s+([A-Z][A1-9]?)", RegexOptions.IgnoreCase | RegexOptions.Multiline)
            .Groups[3].Value)
            .ToArray()
            );

                        cel7 = row.CreateCell(7);//在行中添加一列
                        cel7.SetCellValue(cabins);//设置列的内容

                        cel8 = row.CreateCell(8);//在行中添加一列
                        cel8.SetCellValue(l.PNRNO);//设置列的内容

                        cel9 = row.CreateCell(9);//在行中添加一列
                        cel9.SetCellValue(l.Code);//设置列的内容

                        cell_1 = row.CreateCell(10);//在行中添加一列
                        cell_1.SetCellValue(@"");//设置列的内容
                    //});
                    
                });
                //}
                try
                {
                    workbook.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
                    MessageBox.Show(string.Format("提示信息：\r\n本次数据导出已结束，共生成有 {0} 条有效数据。", lstQuene.Items.Cast<ListViewItem>().Select(l => l.Tag as RequireBook).Count()), @"EXCEL导出提醒", MessageBoxButtons.OK);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("异常信息：\r\n本次数据导出发生异常：{0}。", ex.Message), @"EXCEL导出提醒", MessageBoxButtons.OK);
                }
            }
        }
        #endregion

        #region 导入EXCEL
        /// <summary>
        /// 使用NPOI导入EXCEL
        /// </summary>
        /// <param name="fileName">选择的EXCEL文件</param>
        private void UnpackExcel(string fileName)
        {
            //m_StackPATObject = new Queue<PATObject>();
            List<RequireBook> requireItems = new List<RequireBook>();
            HSSFWorkbook hssfworkbook;
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                hssfworkbook = new HSSFWorkbook(fs);
                for (int sheetIndex = 0; sheetIndex < hssfworkbook.NumberOfSheets; sheetIndex++)
                {
                    ISheet sheet = hssfworkbook.GetSheetAt(sheetIndex);
                    System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
                    //IRow headerRow = sheet.LastRowNum;
                    int cellCount = sheet.LastRowNum;
                    //List<PATObject> rowsCol = new List<PATObject>();
                    while (rows.MoveNext())
                    {
                        HSSFRow row = (HSSFRow)rows.Current;
                        if (row.RowNum == 0) continue;
                        try
                        {
                            RequireBook patObject = new RequireBook()
                            {
                                Key = Guid.NewGuid(),
                                Passengers = new List<Passenger>() { new Passenger() { IdNo = row.Cells[1].ToString(), Name = row.Cells[0].ToString(), Mobile = row.Cells[2].ToString() } },
                                Dept = row.Cells[3].ToString(),
                                DeptDate = row.Cells[6].ToString(),
                                Dest = row.Cells[4].ToString(),
                                RetDate = row.Cells[7].ToString(),
                                AirWay = row.Cells[5].ToString(),
                            };
                            requireItems.Add(patObject);
                            //rowsCol.Add(patObject);
                            ShowPATObject(sheet.SheetName, patObject, Action.ADD);
                        }
                        catch { }

                    }
                }
            }
            MessageBox.Show(string.Format("提示信息：\r\n您已导入了{0}条待处理资源，请执行“开始分析”。", requireItems.Count), @"EXCEL导入提醒", MessageBoxButtons.OK);
            plugInConfig.Requires.AddRange(requireItems);
            plugIn.PlugInConfigJSon = jss.Serialize(plugInConfig);
        }


        #region 日志处理窗口
        public delegate void ShowPATLogDelegate(string CmdStr, string CmdResult, LogAcion log);

        private void ShowPATLog(string CmdStr, string CmdResult, LogAcion log)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new ShowPATLogDelegate(ShowPATLog), CmdStr, CmdResult, log);
                return;
            }
            Color itemColor = Color.Blue;
            switch (log)
            {
                case LogAcion.WARNING:
                    itemColor = Color.Teal;
                    break;
                case LogAcion.DEBUG:
                    itemColor = Color.Crimson;
                    break;
                case LogAcion.ERROR:
                    itemColor = Color.Red;
                    break;
                default:
                    break;
            }
            ListViewItem item = new ListViewItem(new string[] { 
                log.ToString(),
                CmdStr,
                CmdResult,
                DateTime.Now.ToString(@"MM-dd HH;mm:ss")
            });
            item.ForeColor = itemColor;
            item.Font = new Font(System.Drawing.FontFamily.GenericSansSerif, 10, FontStyle.Bold);
            this.lstLog.Items.Add(item);

            this.lstLog.EnsureVisible(this.lstLog.Items.Count - 1);
        }
        #endregion

        public delegate void SheetPATRowDelegate(string SheetName, RequireBook patObject, Action action);

        private void ShowPATObject(string SheetName, RequireBook patObject, Action action)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new SheetPATRowDelegate(ShowPATObject), SheetName, patObject, action);
                return;
            }

            Color itemBackColor = Color.BurlyWood;
            switch (action)
            {
                case Action.ADD:
                    break;
                case Action.NORMAL:
                    itemBackColor = Color.Beige;
                    break;
                case Action.EDIT:
                    itemBackColor = Color.Coral;
                    break;
                case Action.SENT:
                    itemBackColor = Color.DeepSkyBlue;
                    break;
                default:
                    break;
            }

            if (this.lstQuene.Items.Cast<ListViewItem>().Where(l => l.Name == patObject.Key.ToString()).Any())
            {
                var exItem = this.lstQuene.Items.Cast<ListViewItem>().Where(l => l.Name == patObject.Key.ToString()).FirstOrDefault();
                //exItem.SubItems[2].Text = patObject.DeptDate;
                exItem.SubItems[6].Text = string.Join(",", patObject.AvResultItem.ToArray());
                exItem.SubItems[8].Text = patObject.PNRNO;
                exItem.SubItems[9].Text = patObject.Code;
                //exItem.SubItems[5].Text = string.Join(",", patObject.Results.OrderBy(l => l.FlightNo).Select(l => l.FlightNo).ToArray());
                //exItem.SubItems[6].Text = string.Join(",", patObject.Results.OrderBy(l => l.FlightNo).Select(l => l.CabinChar).ToArray());
                //exItem.SubItems[7].Text = string.Join(",", patObject.Results.OrderBy(l => l.FlightNo).Select(l => l.Fare).ToArray());
                exItem.Tag = patObject;
                exItem.BackColor = itemBackColor;
                return;
            }

            ListViewGroup group;
            if (!string.IsNullOrEmpty(SheetName))
            {
                if (!this.lstQuene.Groups.Cast<ListViewGroup>().Where(l => l.Name == SheetName).Any())
                {
                    group = new ListViewGroup()
                    {
                        Name = SheetName,
                        Header = SheetName,
                        HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Center
                    };
                    this.lstQuene.Groups.Add(group);
                }
                else
                {
                    group = this.lstQuene.Groups.Cast<ListViewGroup>().Where(l => l.Name == SheetName).FirstOrDefault();
                }



                ListViewItem item = new ListViewItem(new string[] { 
                    string.Join(",", patObject.Passengers.Select(l=>l.Name).ToArray()),
                    patObject.Dept,
                    patObject.DeptDate,
                    patObject.Dest,
                    patObject.RetDate,
                    patObject.AirWay,
                    @"",@"",@"",@"",@""
                });
                item.Name = patObject.Key.ToString();
                item.Tag = patObject;
                item.Group = group;
                item.BackColor = itemBackColor;
                this.lstQuene.Items.Add(item);
            }


        }

        #endregion

        private void btnPAT_Click(object sender, EventArgs e)
        {
            //if (!(m_StackPATObject.Count == 0))
            {
                lstLog.Items.Clear();
                tabControl1.SelectedTab = tabPage1;

                btnPAT.Text = IsPause ? @"开始分析(&S)" : @"暂停分析(&S)";

                if (IsPause)
                {
                    plugIn.Close();
                }
                if (!IsPause)
                    plugIn.Execute();
                IsPause = !IsPause;
            }
            //else
            //{
            //    if (MessageBox.Show(@"警告信息：\r\n您还没有导入任何待处理资源，是否需要从EXCEL模板中导入数据？", @"EXCEL导入提醒", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            //    {
            //        btnUnPackExcel_Click(sender, e);
            //    }
            //}
        }

        private void btnSetting_Click(object sender, EventArgs e)
        {
            new frmSetting().ShowDialog();
        }

        private void btnHURebrate_Click(object sender, EventArgs e)
        {

        }
    }


    /// <summary>
    /// 队列表处理动作类型
    /// </summary>
    public enum Action : int
    {
        ADD = 1,        //添加
        SENT = 2,        //处理中
        EDIT = 4,       //数据修改
        NORMAL = 8      //完成处理
    }

    public enum LogAcion : int
    {
        INFO = 1,
        DEBUG = 2,
        ERROR = 4,
        WARNING = 8
    }
}
